![]() |
PATH![]() |
This section defines how to use the fields that support isochronous transactions in the version 1.1 USBPB .
When making isochronous calls, you set the pbVersion field in the USBPB parameter block to kUSBIsocPBVersion, and use the isochronous variant of the USBPB parameter block.
Isochronous transfers occur on a per frame basis. Mac OS USB version 1.1 does not implement the per sample method suggested in Chapter 10 of the USB Specification 1.0. This may be added in a future release.
The isochronous transfer implementation requires managing data flow in specific frames. An isochronous pipe has a maximum number of bytes that it can transfer every frame. The pipe can transfer fewer bytes, but it can not transfer more. Each frame can generate its own error code.
To support frames for isochronous transfers, the following new structure is introduced:
typedef struct{
OSStatus frStatus;
UInt16 frReqCount
UInt16 frActCount;
}USBIsocFrame;
This structure encapsualates the transfer for one frame. On entry, the value of the frReqCount field is set to indicate how many bytes are to be transfered (in or out) for this particular frame. (Note 16 bits is more than enough, the maxpacketsize is 1023 bytes, 10 bits).
On completion, the frActCount field indicates how many bytes were actually transfered and the frStatus field specifies the result of the attempt.
For input transfers the frStatus field may return errors, such as:
kUSBUnderRunErr
|
-6907 | Packet received was shorter than expected |
kUSBOverRunErr
|
-6908 | Packet too large or more data than buffer |
kUSBCRCErr
|
-6915 | Pipe stall, bad CRC; packet was received corrupt |
In all of the above cases, there is data in the usbBuffer (it may not be very good data) which the class driver can use as it pleases.
For output, the error code is less interesting, you only know that the packet was launched onto the bus (or not as the case may be). There is not any indication that the data packet was received correctly, or that anyone was listening to it at all.
The usbStatus field returns an overall status for the isochronous transaction. If usbStatus returns with no error, then the status for all of the packets is also no error. If usbStatus is returned with another status value, then all of the individual packets should be examined for error codes. The usbStatus field contains a representitive error if there are multiple packet errors.
The usbBuffer field points to the data, all of the packets to be sent or received are layed end to end.
The usbReqCount and usbActCount fields specify the overall total of data for all the packets sent or received.
The usbReference field is a pipe reference to an isochronous pipe.
The FrameList field ( usb.isoc.FrameList ) in the usbIsocBits structure is a pointer to an array of USBIsocFrame structures that specify the individual packets. The start of any individual packet is found by adding the values in the frReqCount fields for all the preceding packets and adding that to usbBuffer . For example, if the frReqCount values are (61, 62, 63, 64, and so on) and you want the address for the packet to be sent in the third frame, start with the address of usbBuffer and add 61 + 62.
The NumFrames field ( usb.isoc.NumFrames ) is the number of frames pointed to by the FrameList field, and also defines over how many frames the call will be active.
The usbFrame field specifies the frame number on which the transfers are to start. A frame is specified to be the nearest frame to the current frame with the specified low 32 bits when the transfer is called. This method eliminates the need for a 64-bit frame counter as long as the class driver has a latency of less than 23 days.
Isochronous pipes are opened when a USBConfigureInterface function is called. During a call to USBConfigureInterface function, the available bandwidth is checked. If bandwidth is insufficient, the call to open the isochronous pipes could fail.
Previous | Back Up One Level | Next |